package com.yunpuvip.sachet.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunpuvip.sachet.biz.entity.Order;
import com.yunpuvip.sachet.biz.entity.Payment;
import com.yunpuvip.sachet.biz.entity.Player;
import com.yunpuvip.sachet.biz.mapper.OrderMapper;
import com.yunpuvip.sachet.biz.model.params.OrderParam;
import com.yunpuvip.sachet.biz.model.result.OrderResult;
import com.yunpuvip.sachet.biz.service.*;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunpuvip.sachet.modular.constant.ApplicationConstant;
import com.yunpuvip.sachet.modular.constant.enumconstant.*;
import com.yunpuvip.sachet.modular.core.exception.GunsException;
import com.yunpuvip.sachet.modular.core.exception.RestServiceExceptionEnum;
import com.yunpuvip.sachet.modular.factory.QrCodeFactory;
import com.yunpuvip.sachet.modular.page.LayuiPageFactory;
import com.yunpuvip.sachet.modular.page.LayuiPageInfo;
import com.yunpuvip.sachet.modular.vo.rest.request.OrderQueryVo;
import com.yunpuvip.sachet.modular.vo.rest.request.RechargeVo;
import com.yunpuvip.sachet.modular.vo.rest.response.OrderVo;
import com.yunpuvip.sachet.modular.vo.rest.response.RechargePrePayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单信息 服务实现类
 * </p>
 *
 * @author wushaohong
 * @since 2019-08-10
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private GiftInfoService giftInfoService;

    @Autowired
    private SysparamService sysparamService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private OrderService orderServicel;
    @Autowired
    BalanceHistoryService balanceHistoryService;


    @Override
    public void add(OrderParam param){
        Order entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(OrderParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(OrderParam param){
        Order oldEntity = getOldEntity(param);
        Order newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public OrderResult findBySpec(OrderParam param){
        return null;
    }

    @Override
    public List<OrderResult> findListBySpec(OrderParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(OrderParam param){
        Page pageContext = getPageContext();
        Page<Order> orderPage = baseMapper.selectOrderPage(pageContext, param);
        return LayuiPageFactory.createPageInfo(orderPage);
    }

    private Serializable getKey(OrderParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private Order getOldEntity(OrderParam param) {
        return this.getById(getKey(param));
    }

    private Order getEntity(OrderParam param) {
        Order entity = new Order();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    @Override
    public RechargePrePayVo userOrderPack(Integer playerId, RechargeVo rechargeVo) {
        //@NotEmpty(message = "支付类型不能为空") String payType = rechargeVo.getPayType();
        @NotNull(message = "支付金额不能为空") BigDecimal amount = rechargeVo.getAmount();
        //生成订单
        Date expireDate = rechargeVo.getExpireDate();
        String orderNo = "MB" + IdUtil.createSnowflake(1, 1).nextId();
        Order order = new Order();
        //获取赠送金额
        BigDecimal giftAmount = giftInfoService.getGiftAmount(playerId, amount,false);
        order.setTotalPrice(amount);
        //order.setPayPrice(amount);
        order.setOrderDesc("用户订单支付");
        order.setExpireDate(expireDate);
        order.setPlayerId(playerId);
        order.setProduceCode(rechargeVo.getProduceCode());
        order.setOrderStatus(OrderStatus.WAIT_PAY.getStatus());
        order.setPayStatus(PayStatus.WAIT_PAY.getStatus());
        order.setOrderNo(orderNo);
        order.setRemark(rechargeVo.getRemark());
        baseMapper.insert(order);


        //生成缴费单
        Payment payment = new Payment();
        payment.setAmount(amount);
        payment.setOrderNo(orderNo);
        payment.setPayinfo("订单支付");
        payment.setExpireDate(expireDate);
        payment.setAttach("{\"orderNo \" : \" "+  orderNo+ "\"}");
        payment.setPlayerId(playerId);
        payment.setOrderId(order.getId());
        //payment.setPayMethod(Integer.valueOf(payType));
        payment.setPayType(PaymentType.ORDER.getStatus().toString());
        payment.setOrderPayPrice(amount);
        payment.setPayStatus(PayStatus.WAIT_PAY.getStatus());
        paymentService.save(payment);

        //生成二维码
        //String uploadQrcode = createAndUploadQrcode(order.getId(), rechargeVo.getUploadPath());
        RechargePrePayVo rechargePrePayVo = new RechargePrePayVo();
        rechargePrePayVo.setAmount(amount);
        rechargePrePayVo.setOrderNo(orderNo);
        rechargePrePayVo.setPaymentId(payment.getId());



        return rechargePrePayVo;
    }

    @Override
    public RechargePrePayVo userRechagePack(Integer playerId, RechargeVo rechargeVo) {
        //获取充值比例，确定充值的金额
        //@NotEmpty(message = "支付类型不能为空") String payType = rechargeVo.getPayType();
        @NotNull(message = "支付金额不能为空") BigDecimal amount = rechargeVo.getAmount();
        //获取赠送比例，这部分放在支付成功操作
      /*  String vlaue = sysparamService.getSysparamVlaue(ApplicationConstant.GIFTSCALE);
        Double scale = Double.valueOf(vlaue);
        BigDecimal giftMoney = amount.multiply(BigDecimal.valueOf(scale));*/
        BigDecimal total = amount;
        //获取赠送金额
        BigDecimal giftAmount = giftInfoService.getGiftAmount(playerId, amount,true);
        //生成订单
        DateTime expireDate = DateUtil.offsetHour(new Date(), 1);
        String orderNo = "MB" + IdUtil.createSnowflake(1, 1).nextId();
        //生成缴费单
        Payment payment = new Payment();
        //该金额为充的金额
        payment.setAmount(total);
        //该金额为送的
        //获取充值赠送比例
        /*String vlaue = sysparamService.getSysparamVlaue(ApplicationConstant.GIFTSCALE);
        if(StrUtil.isNotEmpty(vlaue)){
            Double scale = Double.valueOf(vlaue);
            BigDecimal giftMoney = amount.multiply(BigDecimal.valueOf(scale));
            payment.setGiftAmount(giftAmount);

        }*/
        payment.setGiftAmount(giftAmount);
        payment.setOrderNo(orderNo);
        payment.setExpireDate(expireDate);
        payment.setPayinfo("充值支付");
        payment.setAttach("{\"orderNo \" : \" "+  orderNo+ "\"}");
        payment.setPlayerId(playerId);
        payment.setPayType(PaymentType.RECHARGE.getStatus().toString());
        //该金额为充的即实际支付金额
        payment.setOrderPayPrice(amount);
        payment.setPayStatus(PayStatus.WAIT_PAY.getStatus());
        paymentService.save(payment);

        //返回账单信息
        RechargePrePayVo rechargePrePayVo = new RechargePrePayVo();
        //该金额为充的即实际支付金额
        rechargePrePayVo.setAmount(amount);
        rechargePrePayVo.setOrderNo(orderNo);
        rechargePrePayVo.setPaymentId(payment.getId());
        return rechargePrePayVo;
    }

    @Override
    public Order getOrderByorderNo(String orderNo) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getOrderNo,orderNo);
        return baseMapper.selectOne(wrapper);
    }

    /**
     * 到时扫码用的
     * @param paymentId
     * @return
     */
    @Override
    public Order getOrderBypaymentId(Integer paymentId) {

        Payment payment = paymentService.getById(paymentId);
        if(ObjectUtil.isNull(payment)){
            throw new GunsException(RestServiceExceptionEnum.DATA_NOT_EXIST);
        }
        Order order = getOrderByorderNo(payment.getOrderNo());
        return order;
    }

    @Override
    public Page<OrderVo> getOrderByCondition(OrderQueryVo vo) {


        Page pageContext = getPageContext();
        /**
         * 将过期订单取消掉
         */
        paymentService.updateExpiredOrderAndPayment();
        Page<OrderVo> orderPageByCondition = baseMapper.getOrderPageByCondition(pageContext, vo);
        System.err.println(orderPageByCondition);
        return orderPageByCondition;
    }

    @Override
    public OrderVo getOrderById(Integer orderId) {
        Order order = baseMapper.selectById(orderId);
        OrderVo orderVo = new OrderVo();
        if(ObjectUtil.isNotNull(order)){
            BeanUtil.copyProperties(order,orderVo);
            Payment payment = paymentService.getPaymentByOrderNo(order.getOrderNo());
            if(ObjectUtil.isNotNull(payment)){
                orderVo.setPaymentId(payment.getId());
            }
        }
        return orderVo;
    }

    @Override
    public void changeOrderPayPrice(BigDecimal sunAmount, Payment payment) {

    }

    @Override
    public boolean drawBackUserBalance(Integer paymentId) {
        Payment payment = paymentService.getById(paymentId);
        //判断是否是订单支付，判断是否不为已支付,
        Integer playerId = payment.getPlayerId();
        Integer orderId = payment.getOrderId();
        Order order = orderServicel.getById(orderId);
        //判断订单状态
        //退款
        balanceHistoryService.DrawBackaAndAddBanlanceHistory(order);
        order.setPayPrice(order.getTotalPrice());
        order.setPayPrice(BigDecimal.ZERO);
        orderServicel.updateById(order);
        payment.setOrderPayPrice(order.getTotalPrice());
        paymentService.updateById(payment);
        return true;
    }

    @Override
    public void updateExpiredOrder() {
        LambdaQueryWrapper<Order> paymentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        paymentLambdaQueryWrapper.lt(Order::getExpireDate,new Date());
        paymentLambdaQueryWrapper.eq(Order::getPayStatus,PayStatus.WAIT_PAY.getStatus());
        List<Order> orderList = baseMapper.selectList(paymentLambdaQueryWrapper);
        orderList.stream().forEach(o->{
            o.setPayStatus(PayStatus.CANCLE.getStatus());
            o.setOrderStatus(OrderStatus.CANCLE.getStatus());
            baseMapper.updateById(o);
        });
    }

    @Override
    public String  createAndUploadQrcode(Integer orderId ,String uploadPath) {
        //拼接二维码地址
        String qrUrl = sysparamService.getSysparamVlaue(ApplicationConstant.QRCODE);
        qrUrl+=orderId;

        //文件夹加上日期
        String fileName = DateUtil.format(new Date(), "yyyyMMdd")+"/"+IdUtil.simpleUUID() + ".png";


        String fileSavePath = uploadPath +fileName;
        File file = new File(fileSavePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        String s = "/img/" + fileName;

        log.debug("upload qrcode fullPath: {}", fileSavePath);
        log.debug("upload qrcode relativePath: {}", "/img/"+fileName);
       // uploadFile.transferTo(new File(fullPath));
        QrCodeFactory.createQrcodeFile(qrUrl,file);
        return  s;
    }
}
